import { vnode, VNode, VNodeData } from './vnode';
import { isVnode } from './isType'
/**
 * 方法的重载
 * @param sel 元素类型
 * @param data 元素属性
 * @param children 元素的子节点
 * @h函数 三种使用形式 
 * 1-->h('div',{class:'list'},h('p',{},'a')) h函数形式
 * 2-->h('div',{class:'list'},'我是div') 字符串形式
 * 3-->h('div',{class:'list'},[
 *  h('p',{},'a'),
 *  h('p',{},'b'),
 *  h('p',{},'c')
 * ]) 数组形式
 */

//h函数形式
export function h(sel: string, data: VNodeData, children: VNode, ele?: Element | undefined): VNode

//字符串形式
export function h(sel: string, data: VNodeData, children: string, ele?: Element | undefined): VNode

//数组形式
export function h(sel: string, data: VNodeData, children: Array<VNode>, ele?: Element | undefined): VNode

//方法的实现
export function h(sel: string, data: VNodeData, children: VNode | string | Array<VNode>, ele?: Element | undefined): VNode {
    const mount: boolean = ele ? false : undefined
    if (isVnode(children)) {
        var newChild: Array<VNode> = [children as VNode]
        return vnode(sel, data, newChild, undefined, ele, mount)
    } else if (typeof children == 'string') {
        return vnode(sel, data, undefined, children, ele, mount)
    } else if (Array.isArray(children)) {
        //循环判断children数组元素里面是否是Vnode对象，如果不是说明参数错误
        for (let value of children) {
            if (!isVnode(value)) throw new Error('h参数错误')
        }
        return vnode(sel, data, children, undefined, ele, mount)
    } else {
        throw new Error('h参数错误')
    }
}